import utils, { NameSpace } from 'utils';
import exceed from 'utils/apimap';
import { getCommitsList } from 'api';

const ns = NameSpace('projectSecurityDependency');

export const UPDATE_DATA = ns('UPDATE_DATA');
export const RESET_DATA = ns('RESET_DATA');
export const UPDATE_PARAM_DATA = ns('UPDATE_PARAM_DATA');

let timer = null;

export function updateData(data) {
  return (dispatch) => {
    dispatch({
      type: UPDATE_DATA,
      data,
    });
  };
}

export function updateTableParams(data) {
  return (dispatch) => {
    dispatch({
      type: UPDATE_PARAM_DATA,
      data,
    });
  };
}

export function resetData() {
  if (timer) clearInterval(timer);
  return (dispatch) => {
    dispatch({
      type: RESET_DATA,
    });
  };
}

export function getBuildResult() {
  return (dispatch, getState) => {
    const { pathResource } = window.FORCE;
    const rootState = getState().project.projectSecurity.root;
    updateData({
      isLoadingBuild: true,
    })(dispatch);
    const params = {
      projectId: pathResource.id,
      branchName: utils.revisionEncodeURI(rootState.branchName),
    };

    let flag = true;
    const func = () => {
      if (params.branchName !== utils.revisionEncodeURI(rootState.branchName)) {
        clearInterval(timer);
      }
      if (flag) {
        flag = false;
        // 需要调用2次，一次为默认状态 pass fail warning 一次为进行中状态 running waiting error;
        const completedPromise = getBuildResultPromise(params, {
          allowed_states: 'PASS,FAIL,WARNING',
          issue_type: 'indirect_dependency',
        });
        const incompletePromise = getBuildResultPromise(params, {
          allowed_states: 'RUNNING,WAITING,ERROR',
          issue_type: 'indirect_dependency',
        });
        Promise.all([completedPromise, incompletePromise])
          .then((responses) => {
            const [completedData, incompleteData] = responses;
            if (
              incompleteData &&
              (incompleteData.state.toLowerCase() === 'running' ||
                incompleteData.state.toLowerCase() === 'waiting')
            ) {
              flag = true;
            } else {
              clearInterval(timer);
              updateData({
                buildResult: completedData,
                incompleteData,
                isLoadingBuild: false,
              })(dispatch);
              if (completedData && completedData.id) {
                updateData({
                  isLoadingBuild: true,
                })(dispatch);
                dispatch(getIssueCount(completedData.id));
                return;
              }
              return;
            }
            updateData({
              buildResult: completedData,
              incompleteData,
              isLoadingBuild: false,
            })(dispatch);
          })
          .catch((err) => {
            console.error(err);
            updateData({
              isLoadingBuild: false,
            })(dispatch);
          });
      }
    };
    timer = setInterval(func, 10000);
    func();
  };
}

// 获取总数
export function getIssueCount(build_result_id) {
  return (dispatch) => {
    const { pathResource } = window.FORCE;

    exceed
      .fetch({
        api: 'projects.builds.get.issue.count',
        params: {
          projectId: pathResource.id,
          build_result_id,
        },
        data: {
          type: 'DEPENDENCY_ANALYSE_FULL',
          issue_type: 'indirect_dependency',
        },
      })
      .then((result) => {
        updateData({
          issueCount: result,
          isLoadingBuild: false,
        })(dispatch);
      });
  };
}

// 开启扫描
export function startScan() {
  return (dispatch, getState) => {
    const { pathResource, user } = window.FORCE;
    const rootState = getState().project.projectSecurity.root;
    updateData({
      isStarting: true,
    })(dispatch);
    // 获取最近的commitID
    getCommitsList({
      ref_name: utils.revisionEncodeURI(rootState.branchName),
      page: 1,
      per_page: 1,
    }).then((res) => {
      const commitId = res[1] ? res[1].id : '';
      exceed
        .fetch({
          api: 'projects.builds.manual',
          params: {
            projectId: pathResource.id,
            branchName: utils.revisionEncodeURI(rootState.branchName),
            userId: user.codeUserId,
            commitId,
            buildTask: 'DEPENDENCY_ANALYSE_FULL',
          },
        })
        .then(() => {
          updateData({
            isStarting: false,
          })(dispatch);
          dispatch(getBuildResult());
        })
        .fail((err) => {
          console.error(err);
          updateData({
            isStarting: false,
          })(dispatch);
        });
    });
  };
}

/**
 * 重新扫描
 */
export function restartScan() {
  return (dispatch, getState) => {
    const { pathResource } = window.FORCE;
    const { buildResult } = getState().project.projectSecurity.dependencyAnalysis;
    updateData({
      isStarting: true,
    })(dispatch);
    exceed
      .fetch({
        api: 'projects.builds.manual.retry',
        params: {
          projectId: pathResource.id,
        },
        data: {
          build_result_id: buildResult.id,
        },
      })
      .then(() => {
        updateData({
          isStarting: false,
        })(dispatch);
        dispatch(getBuildResult());
      })
      .fail(() => {
        updateData({
          isStarting: false,
        })(dispatch);
      });
  };
}

function getBuildResultPromise(params, data = {}) {
  return new Promise((resolve) => {
    exceed
      .fetch({
        api: 'projects.builds.get.latest.result',
        params,
        data: {
          // DEPENDENCY_ANALYSE_FULL DEPENDENCY_ANALYSE_INCREMENTAL
          build_task_name: 'DEPENDENCY_ANALYSE_FULL',
          ...data,
        },
      })
      .then((res) => {
        resolve(res);
      })
      .fail(() => {
        resolve(null);
      });
  });
}
